import { apiStore } from '@/utils/store/apiStore'
import { Switch } from '@arco-design/web-react'
import { debounce, groupBy } from 'lodash-es'
import React from 'react'
import ApiRow from './ApiRow'
import { enableSorter } from './useGroup'
import { IGroupItem } from '@/utils/interfaces'

export interface ISearchResultProps {
    keyword?: string
}

interface ISearchResultItem {
    groups: IGroupItem[]
    apis: IApiItem[]
    // 排序索引
    sortIndex?: number
}

const SearchResult: React.FC<ISearchResultProps> = ({ keyword }) => {
    // 搜索结果
    const [searchResults, setSearchResults] = useState<ISearchResultItem[]>([])

    // 搜索
    const handleSearch = async (value: string) => {
        if (!value) {
            setSearchResults([])
            return
        }
        const list = await apiStore.getAllList()
        // 分组map，筛选的同时把分组map也构建出来
        const groupMap: Record<string, { index: number; group: IGroupItem }> =
            {}
        const filtered = list?.filter((item, index) => {
            if (item.type === 'group') {
                groupMap[item.id] = {
                    index,
                    group: item,
                }
            }
            if (item.type !== 'api') {
                return false
            }

            const loverCasedValue = value.toLowerCase()

            // 是否匹配
            // 先匹配 label 和 url
            let isMatch =
                item.label.toLowerCase().includes(loverCasedValue) ||
                item.url?.toLowerCase().includes(loverCasedValue) ||
                false

            // 再匹配 expect的label
            if (!isMatch && item.expects?.length) {
                isMatch =
                    item.expects.some((expect) =>
                        expect.label.toLowerCase().includes(loverCasedValue),
                    ) || false
            }

            // 再匹配 variables的name
            if (!isMatch && item.variables?.length) {
                isMatch =
                    item.variables.some((variable) =>
                        variable.name.toLowerCase().includes(loverCasedValue),
                    ) || false
            }

            return isMatch
        })
        const sorted = filtered.sort(enableSorter)
        const grouped = groupBy(sorted, 'parentId')
        const results: ISearchResultItem[] = []
        Object.keys(grouped).forEach((parentId) => {
            let groups: IGroupItem[] = []
            let sortIndex = 0
            if (parentId) {
                let pId: string | undefined = parentId
                while (pId) {
                    const groupItem:
                        | { index: number; group: IGroupItem }
                        | undefined = groupMap[pId]
                    if (groupItem) {
                        groups.unshift(groupItem.group)
                        sortIndex += groupItem.index
                    }
                    pId = groupItem?.group?.parentId
                }
            }
            results.push({
                sortIndex,
                groups,
                apis: grouped[parentId] as IApiItem[],
            })
        })
        const sortedResults = results.sort(
            (a, b) => (a.sortIndex || 0) - (b.sortIndex || 0),
        )
        setSearchResults((sortedResults as ISearchResultItem[]) || [])
    }

    const debouncedHandleSearch = debounce(handleSearch, 300)

    // 更改enabled
    const handleGroupChange = async (item: IListItem, enabled: boolean) => {
        const cloned = { ...item }
        cloned.enabled = enabled
        await apiStore.save(cloned)
        handleSearch(keyword || '')
    }

    useEffect(() => {
        debouncedHandleSearch(keyword || '')
    }, [keyword])

    return (
        <div className='h-full flex flex-col'>
            {/* 内容 */}
            <div className='min-h-[200px] flex-1 overflow-y-auto px-2'>
                {searchResults?.map((item, index) => {
                    return (
                        <div key={index} className='my-1 '>
                            {/* 分组 */}
                            {!!item.groups?.length && (
                                <div className='flex items-center rounded bg-gray-100 p-1'>
                                    {item.groups?.map((group) => {
                                        return (
                                            <div key={group.id}>
                                                {group?.label}{' '}
                                                <Switch
                                                    className='mx-1'
                                                    size='small'
                                                    checked={group.enabled}
                                                    onChange={(v) =>
                                                        handleGroupChange(
                                                            group,
                                                            v,
                                                        )
                                                    }
                                                />
                                                <span className='mx-1'>/</span>
                                            </div>
                                        )
                                    })}
                                </div>
                            )}
                            {item.apis.map((api) => {
                                return <ApiRow key={api.id} apiItem={api} />
                            })}
                        </div>
                    )
                })}
            </div>
        </div>
    )
}

export default SearchResult
